package cn.keniykey.mc.landterritory.landview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import javax.annotation.Nullable;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import cn.keniykey.mc.landterritory.config.ConfigurationManager;
import cn.keniykey.mc.landterritory.config.LanguageManager;
import cn.keniykey.mc.landterritory.config.ViewsConfiguration;
import cn.keniykey.mc.landterritory.config.ViewsConfiguration.ViewConfig;
import cn.keniykey.mc.landterritory.event.LandFlagRestEvent;
import cn.keniykey.mc.landterritory.event.LandFlagUpdateEvent;
import cn.keniykey.mc.landterritory.land.api.ELandType;
import cn.keniykey.mc.landterritory.land.api.Land;
import cn.keniykey.mc.landterritory.land.api.LandUtil;
import cn.keniykey.mc.landterritory.land.api.LandUtil.ELandPermissionLevel;
import cn.keniykey.mc.landterritory.landflag.LandFlag;
import cn.keniykey.mc.landterritory.landflag.LandFlagManager;
import cn.keniykey.mc.landterritory.landflag.api.ELandFlagParType;
import cn.keniykey.mc.landterritory.landflag.api.ILandFlagDetection;
import cn.keniykey.mc.landterritory.landflag.api.JavaLandFlag;
import cn.keniykey.mc.landterritory.landflag.api.LandFlagSetting;
import cn.keniykey.mc.landterritory.toolkit.Util;
import cn.keniykey.mc.viewlibrary.container.api.EContainerType;
import cn.keniykey.mc.viewlibrary.view.api.AbFrameView;
import cn.keniykey.mc.viewlibrary.view.api.FrameViewBundle;
import cn.keniykey.mc.viewlibrary.view.api.FrameViewIntent;
import cn.keniykey.mc.viewlibrary.view.api.IViewClickHandler;
import cn.keniykey.mc.viewlibrary.view.api.ViewClickReport;
import cn.keniykey.mc.viewlibrary.view.api.template.AbChooseView;
import cn.keniykey.mc.viewlibrary.view.api.template.ChooseViewIntentBuilder;

public final class LandFlagListView extends AbLandFrameView{

	protected LandFlagListView(Player player1) {
		super(player1);
	}
	
	private static final String VIEW_NAME = "landflags";
	private Land land;
	private int page = 1,page_max;
	private ArrayList<LandFlag> list_flags;
	private boolean sold_show = false;
	
	private static final int CODE_CHOOSE_REST = 10200;
	private static final int CODE_CHOOSE_REMOVE = 10201;
	
	@Override
	protected void onCreate() {
		super.onCreate();
		final FrameViewBundle bundle = this.getIntent().getExtras();
		
		this.land = bundle.getValue("land", null);
		this.sold_show = bundle.getValue("sold", false);
		
		this.setViewType(EContainerType.GENERIC_6X9);
		this.list_flags = new ArrayList<>(LandFlagManager.getFlagManager().getLandFlags());
		this.page_max = ((this.list_flags.size() / 45) + 1);
		
		final ViewConfig config_view = ViewsConfiguration.getViewConfig(VIEW_NAME);
		this.setIconClick(49, config_view.getViewItem("back"), AbLandFrameView.CLICK_BACK);
		if(!this.sold_show) {
			if(!ELandType.GROUND.equals(this.land.getType())) {
				this.setIconClick(45, config_view.getViewItem("rest1"), new IViewClickHandler() {
					@Override
					public void onClick(Player player, AbFrameView view, ViewClickReport report) {
						if(!LandFlagListView.this.isMatchClickSpeed()) return;
						final ChooseViewIntentBuilder builder = new ChooseViewIntentBuilder(LandChooseView.class);
						builder.setChooseCountdown(ConfigurationManager.View_Choose_Countdown);
						builder.setCustomPromptName(LanguageManager.getLang(1102102, LanguageManager.getLang(1102100)));
						builder.setCustomPromptLore(Util.listFromStr(LanguageManager.getLang(1102103,
								LandViewUtil.getLandLabelStr(LandFlagListView.this.land))));
						LandFlagListView.this.showViewForResult(builder.build(), CODE_CHOOSE_REST);
					}
				});
			}else {
				this.setIconClick(45, config_view.getViewItem("rest2"), new IViewClickHandler() {
					@Override
					public void onClick(Player player, AbFrameView view, ViewClickReport report) {
						if(!LandFlagListView.this.isMatchClickSpeed()) return;
						final FrameViewIntent intent = new FrameViewIntent(LandFlagRestView.class);
						final FrameViewBundle fvb = new FrameViewBundle();
						fvb.putValue("land", LandFlagListView.this.land);
						intent.putExtras(fvb);
						view.showView(intent);
					}
				});
			}
			this.setIconClick(53, config_view.getViewItem("add"), new IViewClickHandler() {
				@Override
				public void onClick(Player player, AbFrameView view, ViewClickReport report) {
					if(!LandFlagListView.this.isMatchClickSpeed()) return;
					if(!LandUtil.hasLandPermission(player, LandFlagListView.this.land, ELandPermissionLevel.FLAG_LANDADMIN)) return;
					final FrameViewIntent intent = new FrameViewIntent(LandFlagAddView.class);
					final FrameViewBundle fvb = new FrameViewBundle();
					fvb.putValue("land", LandFlagListView.this.land);
					intent.putExtras(fvb);
					view.showView(intent);
				}
			});
		}
		this.setIconClick(47, config_view.getViewItem("last"), new IViewClickHandler() {	
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(LandFlagListView.this.page <= 1) return;
				if(!LandFlagListView.this.isMatchClickSpeed()) return;
				LandFlagListView.this.page--;
				LandFlagListView.this.refreshPage();
			}
		});
		this.setIconClick(51, config_view.getViewItem("next"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(LandFlagListView.this.page >= LandFlagListView.this.page_max) return;
				if(!LandFlagListView.this.isMatchClickSpeed()) return;
				LandFlagListView.this.page++;
				LandFlagListView.this.refreshPage();
			}
		});
	}
	@Override
	protected void onShowBefore() {
		this.refreshPage();
	}
	
	private void refreshPage() {
		if(this.page < 1) this.page = 1;
		if(this.page > this.page_max) this.page = this.page_max;
		for(int index = 0; index < 45; index++) this.getContainer().setItemStack(index, null, false);
		this.clearIconsClick(0, 44);
		final IViewClickHandler handler = new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(report.isLeftClick()) {
					if(!LandFlagListView.this.isMatchClickSpeed()) return;
					final int row = this.getPageIndex(report.getClickRawSlot());
					if(row >= LandFlagListView.this.list_flags.size()) return;
					final LandFlag flag = LandFlagListView.this.list_flags.get(row);
					if(!LandUtil.hasLandPermission(player, LandFlagListView.this.land, LandViewUtil.getLandFLagMinPermissionLevel(flag))) return;
					final ILandFlagDetection dete_click = LandFlagSetting.getClickDetection(flag.getName());
					if(dete_click != null) {
						try {
							if(!dete_click.onRequest(player, LandFlagListView.this.land)) return;
						}catch(Exception ex) {
							ex.printStackTrace();
						}
					}
					if(ELandFlagParType.NONE.equals(flag.getELandFlagParType())) return;
					
					final FrameViewIntent intent = new FrameViewIntent(LandFlagInfoView.class);
					final FrameViewBundle fvb = new FrameViewBundle();
					fvb.putValue("land", LandFlagListView.this.land);
					fvb.putValue("landflag", flag);
					intent.putExtras(fvb);
					view.showView(intent);
					return;
				}
				if(!report.isRightClick()) return;
				if(!LandFlagListView.this.isMatchClickSpeed()) return;
				final int row = this.getPageIndex(report.getClickRawSlot());
				if(row >= LandFlagListView.this.list_flags.size()) return;
				final LandFlag flag = LandFlagListView.this.list_flags.get(row);
				
				final ChooseViewIntentBuilder builder = new ChooseViewIntentBuilder(LandChooseView.class);
				builder.setChooseCountdown(ConfigurationManager.View_Choose_Countdown);
				builder.setCustomPromptName(LanguageManager.getLang(1102102, LanguageManager.getLang(1102150)));
				builder.setCustomPromptLore(Util.listFromStr(LanguageManager.getLang(1102152,
						LandViewUtil.getLandLabelStr(LandFlagListView.this.land), flag.getDisplayName())));
				builder.setForwardContent(flag);
				LandFlagListView.this.showViewForResult(builder.build(), CODE_CHOOSE_REMOVE);
			}
			private int getPageIndex(int row) {
				return (((LandFlagListView.this.page - 1) * 45) + row);
			}
		};
		final int begin_flag_index = ((this.page - 1) * 45);
		final ViewConfig config_view = ViewsConfiguration.getViewConfig(VIEW_NAME);
		final ItemStack item_backup = config_view.getViewItem("about");
		for(int index = 0,flag_index = begin_flag_index, flag_max_index = this.list_flags.size();
				flag_index < flag_max_index && index < 45; index++,flag_index++) {
			final LandFlag landflag = this.list_flags.get(flag_index);
			if(!this.land.getFlags().containsKey(landflag.getName())) continue;
			this.getContainer().setItemStack(index, this.getLandFlagInfoItemStack(item_backup, landflag), false);
			if(!this.sold_show) this.setIconClick(index, handler);
		}
		this.setTitle(Util.conver(Util.setStr(config_view.getViewTitle(), this.page, this.page_max)));
	}
	private ItemStack getLandFlagInfoItemStack(ItemStack item_backup, LandFlag landflag) {
		final String flagname = landflag.getName();
		final ELandFlagParType partype = landflag.getELandFlagParType();
		final ItemStack item = item_backup.clone();
		final ItemMeta meta = item.getItemMeta();
		meta.setDisplayName(meta.getDisplayName() + landflag.getDisplayName());
		final StringBuilder builder_str = new StringBuilder();
		if(!this.sold_show) {
			if(!ELandFlagParType.NONE.equals(partype)) {
				builder_str.append(LanguageManager.getLang(1102004)).append("\n");
			}
			builder_str.append(LanguageManager.getLang(1102003)).append("\n");
		}
		builder_str.append(LanguageManager.getLang(1102000, flagname,
				LanguageManager.getLang(partype.getLandID())));
		final List<String> indulist = landflag.getIntroductionLore();
		if(indulist != null && !indulist.isEmpty()) {
			builder_str.append("\n").append(LanguageManager.getLang(1102001));
			for(final String str_indu : indulist) {
				builder_str.append("\n ").append(str_indu);
			}
		}
		
		final Set<String> flag_pars = this.land.getFlags().get(flagname);
		//不用判断存在，因为调用此方法前已经判断存在，只要存在要么不可修改空Set，否则就是可修改的HashSet
		if(!flag_pars.isEmpty()) {
			builder_str.append("\n").append(LanguageManager.getLang(1102002));
			if(flag_pars.contains(JavaLandFlag.ALL_PAR_STR)) {
				builder_str.append("\n").append(LanguageManager.getLang(1003000));
			}else {
				int length = 0;
				for(final String str : flag_pars) {
					builder_str.append((0 == length ? "\n " : "§e, "));
					builder_str.append("§r").append(str);
					length++;
					if(length > 4) length = 0; //一行最多5个参数显示
				}
			}
		}
		meta.setLore(Util.listFromStr(builder_str.toString()));
		item.setItemMeta(meta);
		return item;
	}
	
	@Override
	protected void onViewResult(int requestcode, int resultcode, @Nullable FrameViewBundle bundle) {
		super.onViewResult(requestcode, resultcode, bundle);
		switch(AbChooseView.EChooseResult.muchResult(resultcode)) {
		case CONFIRM:
			if(CODE_CHOOSE_REST == requestcode) {
				restLandFlag(this.getPlayer(),this.land);
				return;
			}
			if(CODE_CHOOSE_REMOVE == requestcode) {
				this.removeLandFlag(bundle.getValue(AbChooseView.EChooseResultIntentKey.FORWARD.toString(), null));
				return;
			}
			this.getPlayer().sendMessage(LanguageManager.getChatLang(1001001) + requestcode);
			break;
		case VETO: return;
		default:
		}
		this.finishAll();
	}
	
	static void restLandFlag(final Player player,final Land land) {
		if(!LandUtil.hasLandPermission(player, land, ELandPermissionLevel.OWNER)) {
			player.sendMessage(LanguageManager.getChatLang(1005000, LandViewUtil.getLandLabelStr(land), 
					LanguageManager.getLang(1102100)));
			return;
		}
		
		final HashMap<String,Set<String>> landflags = LandFlagManager.getFlagManager().getInitialLandFlags(land.getType());;
		for(Set<String> pars : land.getFlags().values()) {
			if(!pars.isEmpty()) pars.clear();
		}
		land.getFlags().clear();
		land.getFlags().putAll(landflags);
		landflags.clear();
		land.updateFlags();
		Bukkit.getPluginManager().callEvent(new LandFlagRestEvent(player, land));
		player.sendMessage(LanguageManager.getChatLang(1102101, LandViewUtil.getLandLabelStr(land)));
	}
	private void removeLandFlag(LandFlag flag) {
		final Player player = this.getPlayer();
		if(!LandUtil.hasLandPermission(player, this.land, LandViewUtil.getLandFLagMinPermissionLevel(flag))) {
			player.sendMessage(LanguageManager.getChatLang(1005000, LandViewUtil.getLandLabelStr(this.land), 
					LanguageManager.getLang(1102150)));
			return;
		}
		
		final ILandFlagDetection dete_remove = LandFlagSetting.getRemoveDetection(flag.getName());
		if(dete_remove != null) {
			try {
				if(!dete_remove.onRequest(player, this.land)) {
					player.sendMessage(LanguageManager.getChatLang(1102153, LandViewUtil.getLandLabelStr(this.land),
							flag.getDisplayName()));
					return;
				}
			}catch(Exception ex) {
				ex.printStackTrace();
			}
		}
		final String flagname = flag.getName();
		if(this.land.getFlags().containsKey(flagname)) {
			final Set<String> pars = this.land.getFlags().get(flagname);
			if(!pars.isEmpty()) pars.clear();
			this.land.getFlags().remove(flagname);
			this.land.updateFlags();
			Bukkit.getPluginManager().callEvent(new LandFlagUpdateEvent(player, this.land, flag));
		}
		player.sendMessage(LanguageManager.getChatLang(1102151, flag.getDisplayName(), LandViewUtil.getLandLabelStr(this.land)));
	}
}